package com.jnu.happyrunningwithmusic;

import static android.content.ContentValues.TAG;
import static com.jnu.happyrunningwithmusic.util.IOfflineResourceConst.DEFAULT_SDK_TTS_MODE;
import static com.jnu.happyrunningwithmusic.util.IOfflineResourceConst.PARAM_SN_NAME;
import static com.jnu.happyrunningwithmusic.util.IOfflineResourceConst.TEXT_MODEL;
import static com.jnu.happyrunningwithmusic.util.IOfflineResourceConst.VOICE_MALE_MODEL;

import android.Manifest;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;

import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.AudioManager;
import android.os.Bundle;

import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.Polyline;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.utils.DistanceUtil;
import com.baidu.speech.EventListener;
import com.baidu.speech.EventManagerFactory;
import com.baidu.speech.asr.SpeechConstant;
import com.baidu.tts.chainofresponsibility.logger.LoggerProxy;
import com.baidu.tts.client.SpeechError;
import com.baidu.tts.client.SpeechSynthesizer;
import com.baidu.tts.client.SpeechSynthesizerListener;
import com.baidu.tts.client.TtsMode;
import com.jnu.happyrunningwithmusic.control.InitConfig;
import com.jnu.happyrunningwithmusic.listener.UiMessageListener;
import com.jnu.happyrunningwithmusic.util.Auth;
import com.jnu.happyrunningwithmusic.util.AutoCheck;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import com.baidu.speech.EventManager;
import com.google.gson.Gson;

public class MainActivity extends AppCompatActivity implements EventListener {
    //计时器相关变量
    private int minute = 0;//这是分钟
    private int second = 0;
    private boolean flag=true;
    private TextView timeView1;
    //定位相关变量
    private double distance=0;
    private int yuan=0; //一首歌曲播放过程中定位的点数
    private double average_speed;
    private boolean isRunning=true;
    private Button start;
    private Button pause;
    private Button stop;
    private TextView speedText;
    private TextView distanceText;
    private MapView mMapView;
    private BaiduMap mBaiduMap;
    private TextView type;
    private boolean isFirstLoc=true;
    private MyLocationConfiguration.LocationMode locationMode;
    private LocationClient mLocClient;

    private BDAbstractLocationListener myListener;

    private LatLng firstLaLng;
    private LatLng latLng;
    private List<LatLng> ppp;
    private LocationClientOption option;

    //音乐相关变量
    public static final int UPDATE_PROGESS=0;
    private ImageButton imageButton;
    private SeekBar seekBar;
    private Button next;
    private MyConnection conn;
    private MusicService.MyBinder musicController;
    private Handler handler=new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(android.os.Message msg){
            switch (msg.what){

                case UPDATE_PROGESS:
                    if(musicController.isPlaying())
                    {
                        upDateProgress();
                    }
                    else {
                        Log.i("isPlaying","nooooooooooooooooo");
                        yuan =1;
                        musicController.reset(average_speed);
                        if(average_speed>10)
                            type.setText("当前播放歌曲类别：快歌");
                        else if(average_speed>6)
                            type.setText("当前播放歌曲类别：轻快");
                        else type.setText("当前播放歌曲类别：抒情");
                        seekBar.setMax(musicController.getDuration());
                        seekBar.setProgress(musicController.getCurrentPosition());
                        upDateProgress();
                    }
                    break;
                case 1:
                    if(second>58){
                        minute++;
                        second=0;
                        MainActivity.this.timeView1.setText(minute+":0"+second);
                    }
                    else{
                        if(second<9){
                            second++;
                            MainActivity.this.timeView1.setText(minute+":0"+second);
                        }
                        else{
                            second++;
                            MainActivity.this.timeView1.setText(minute+":"+second);
                        }
                    }
                    if(minute%30==0&&second%(30*60)==0){
                        speak("你已经跑了"+minute+"分钟，加油");
                    }
                default:

                    break;
            }

        }
    };
    //语音合成相关变量
    protected String appId;
    protected String appKey;
    protected String secretKey;
    protected String sn;
    // TtsMode.MIX; 离在线融合，在线优先； TtsMode.ONLINE 纯在线； 没有纯离线
    private TtsMode ttsMode = DEFAULT_SDK_TTS_MODE;
    protected Handler mainHandler;
    private boolean isOnlineSDK = TtsMode.ONLINE.equals(DEFAULT_SDK_TTS_MODE);
    // ================ 纯离线sdk或者选择TtsMode.ONLINE  以下参数无用;
    private static final String TEMP_DIR = "/sdcard/baiduTTS"; // 重要！请手动将assets目录下的3个dat 文件复制到该目录
    // 请确保该PATH下有这个文件
    private static final String TEXT_FILENAME = TEMP_DIR + "/" + TEXT_MODEL;
    // 请确保该PATH下有这个文件 ，m15是离线男声
    private static final String MODEL_FILENAME = TEMP_DIR + "/" + VOICE_MALE_MODEL;
    protected SpeechSynthesizer mSpeechSynthesizer;
    private static String TEXT="开始跑步";

    //语音识别相关变量
    protected ImageButton startBtn;//开始识别  一直不说话会自动停止，需要再次打开
    public static EventManager asr;//语音识别核心库
    MyBluetooth bluetooth = new MyBluetooth();
    SpeechListener speechListener;
    private DrawThread drawThread;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.activity_main);

        //初始化语音合成
        appId = Auth.getInstance(this).getAppId();
        appKey = Auth.getInstance(this).getAppKey();
        secretKey = Auth.getInstance(this).getSecretKey();
        sn = Auth.getInstance(this).getSn(); // 纯离线合成必须有此参数；离在线合成SDK没有此参数
        initView();
        initPermission();
        initPermissionhe();

        initTTs();

        //初始化定位
        initLocation();
        start=findViewById(R.id.start);
        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                StartSport();
            }
        });
        pause=findViewById(R.id.pause);
        pause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                pauseSport();
            }
        });
        stop=findViewById(R.id.stop);
        stop.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                StopSport();
            }
        });
        timeView1=findViewById(R.id.textView);
        speedText=findViewById(R.id.speed);
        distanceText=findViewById(R.id.distance);
        type=findViewById(R.id.textView2);
        //初始化音乐

        imageButton=findViewById(R.id.control);
        seekBar=findViewById(R.id.seekBar);
        next=findViewById(R.id.next);
        Intent service =new Intent(this,MusicService.class);
        startService(service);
        conn= new MyConnection();
        bindService(service,conn,BIND_AUTO_CREATE);
        //切换到下一首
        next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                yuan =1;
                musicController.reset(average_speed);
                if(average_speed>10)
                    type.setText("当前播放歌曲类别：快歌");
                else if(average_speed>6)
                    type.setText("当前播放歌曲类别：轻快");
                else type.setText("当前播放歌曲类别：抒情");
            }
        });
        imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(average_speed>10)
                    type.setText("当前播放歌曲类别：快歌");
                else if(average_speed>6)
                    type.setText("当前播放歌曲类别：轻快");
                else type.setText("当前播放歌曲类别：抒情");
                musicController.playPause();
                UpdatePlayIcon();
            }
        });
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if(fromUser){
                    musicController.seekTo(progress);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        //语音识别
        //初始化EventManager对象
        asr = EventManagerFactory.create(this, "asr");
        //注册自己的输出事件类
        asr.registerListener((EventListener) this); //  EventListener 中 onEvent方法

        //bluetooth.initBlueToothHeadset(this,this);

        //百度语音播报回调接口
        speechListener = new SpeechListener(bluetooth);
        drawThread = new DrawThread();
        drawThread.start();
    }

    private void StartSport() {
        start.setVisibility(View.GONE);
        startMethod1();
        speak(TEXT);
    }

    private void StopSport() {
        flag=false;
        isRunning=false;
        speak("恭喜你已经完成运动");
        drawThread.myStop();
        try {
            drawThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Toast.makeText(MainActivity.this,"恭喜你已经完成运动",Toast.LENGTH_LONG).show();
    }

    private void pauseSport() {
        if(flag){
            flag=false;
            pause.setText("继续");
            stop.setVisibility(View.VISIBLE);
        }
        else{
            flag=true;
            pause.setText("暂停");
            stop.setVisibility(View.GONE);
            startMethod1();
        }
    }

    //初始化语音合成
    private void initTTs() {
        LoggerProxy.printable(true); // 日志打印在logcat中
        boolean isSuccess;
        if (!isOnlineSDK) {
            // 检查2个离线资源是否可读
            isSuccess = checkOfflineResources();
            if (!isSuccess) {
                return;
            } else {
                print("离线资源存在并且可读, 目录：" + TEMP_DIR);
            }
        }
        // 日志更新在UI中，可以换成MessageListener，在logcat中查看日志
        SpeechSynthesizerListener listener = new UiMessageListener(mainHandler);

        // 1. 获取实例
        mSpeechSynthesizer = SpeechSynthesizer.getInstance();
        mSpeechSynthesizer.setContext(this);

        // 2. 设置listener
        mSpeechSynthesizer.setSpeechSynthesizerListener(listener);

        // 3. 设置appId，appKey.secretKey
        int result = mSpeechSynthesizer.setAppId(appId);
        result = mSpeechSynthesizer.setApiKey(appKey, secretKey);


        // 4. 如果是纯离线SDK需要离线功能的话
        if (!isOnlineSDK) {
            // 文本模型文件路径 (离线引擎使用)， 注意TEXT_FILENAME必须存在并且可读
            mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, TEXT_FILENAME);
            // 声学模型文件路径 (离线引擎使用)， 注意TEXT_FILENAME必须存在并且可读
            mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, MODEL_FILENAME);

            mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer.MIX_MODE_DEFAULT);
            // 该参数设置为TtsMode.MIX生效。
            // MIX_MODE_DEFAULT 默认 ，wifi状态下使用在线，非wifi离线。在线状态下，请求超时6s自动转离线
            // MIX_MODE_HIGH_SPEED_SYNTHESIZE_WIFI wifi状态下使用在线，非wifi离线。在线状态下， 请求超时1.2s自动转离线
            // MIX_MODE_HIGH_SPEED_NETWORK ， 3G 4G wifi状态下使用在线，其它状态离线。在线状态下，请求超时1.2s自动转离线
            // MIX_MODE_HIGH_SPEED_SYNTHESIZE, 2G 3G 4G wifi状态下使用在线，其它状态离线。在线状态下，请求超时1.2s自动转离线



        }

        // 5. 以下setParam 参数选填。不填写则默认值生效
        // 设置在线发声音人： 0 普通女声（默认） 1 普通男声  3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
        // 设置合成的音量，0-15 ，默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "9");
        // 设置合成的语速，0-15 ，默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "5");
        // 设置合成的语调，0-15 ，默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5");

        // mSpeechSynthesizer.setAudioStreamType(AudioManager.MODE_IN_CALL); // 调整音频输出

        if (sn != null) {
            // 纯离线sdk这个参数必填；离在线sdk没有此参数
            mSpeechSynthesizer.setParam(PARAM_SN_NAME, sn);
        }

        // x. 额外 ： 自动so文件是否复制正确及上面设置的参数
        Map<String, String> params = new HashMap<>();
        // 复制下上面的 mSpeechSynthesizer.setParam参数
        // 上线时请删除AutoCheck的调用
        if (!isOnlineSDK) {
            params.put(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, TEXT_FILENAME);
            params.put(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, MODEL_FILENAME);
        }

        // 检测参数，通过一次后可以去除，出问题再打开debug
        InitConfig initConfig = new InitConfig(appId, appKey, secretKey, ttsMode, params, listener);
        AutoCheck.getInstance(getApplicationContext()).check(initConfig, new Handler() {
            @Override
            /**
             * 开新线程检查，成功后回调
             */
            public void handleMessage(Message msg) {
                if (msg.what == 100) {
                    AutoCheck autoCheck = (AutoCheck) msg.obj;
                    synchronized (autoCheck) {
                        String message = autoCheck.obtainDebugMessage();
                        print(message); // 可以用下面一行替代，在logcat中查看代码
                        // Log.w("AutoCheckMessage", message);
                    }
                }
            }

        });

        // 6. 初始化
        result = mSpeechSynthesizer.initTts(ttsMode);

    }

    /**
     * 在线SDK不需要调用，纯离线SDK会检查资源文件
     *
     * 检查 TEXT_FILENAME, MODEL_FILENAME 这2个文件是否存在，不存在请自行从assets目录里手动复制
     *
     * @return 检测是否成功
     */
    private boolean checkOfflineResources() {
        String[] filenames = {TEXT_FILENAME, MODEL_FILENAME};
        for (String path : filenames) {
            File f = new File(path);
            if (!f.canRead()) {
                print("[ERROR] 文件不存在或者不可读取，请从demo的assets目录复制同名文件到："
                        + f.getAbsolutePath());
                print("[ERROR] 初始化失败！！！");
                return false;
            }
        }
        return true;
    }

    private void speak(String text) {
        /* 以下参数每次合成时都可以修改
         *  mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
         *  设置在线发声音人： 0 普通女声（默认） 1 普通男声  3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
         *  mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "5"); 设置合成的音量，0-15 ，默认 5
         *  mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "5"); 设置合成的语速，0-15 ，默认 5
         *  mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5"); 设置合成的语调，0-15 ，默认 5
         *
         */

        mSpeechSynthesizer.speak(text);

    }

    private void initView() {
        mainHandler = new Handler() {
            /*
             * @param msg
             */
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.obj != null) {
                    print(msg.obj.toString());
                }
            }

        };
        //语音识别
        startBtn = (ImageButton) findViewById(R.id.bt_start);
        startBtn.setOnTouchListener(buttonListener);
    }

    private View.OnTouchListener buttonListener = new View.OnTouchListener() {

        public boolean onTouch(View arg0, MotionEvent event) {
            // TODO Auto-generated method stub
            int action = event.getAction();
            if (action == MotionEvent.ACTION_DOWN) {
                asr.send(SpeechConstant.ASR_START, "{}", null, 0, 0);
                // 按下 处理相关逻辑
            } else if (action == MotionEvent.ACTION_UP) {
// 松开 todo 处理相关逻辑
                asr.send(SpeechConstant.ASR_STOP, "{}", null, 0, 0);
            }
            return false;

        }
    };


    private void print(String message) {
        Log.i(TAG, message);
    }

    private void initLocation(){

        mMapView=findViewById(R.id.bmapView);
        mBaiduMap=mMapView.getMap();
        ppp=new ArrayList<LatLng>();


        mLocClient=new LocationClient(this);

        if(mLocClient != null&& !mLocClient.isStarted()){
            mLocClient.requestLocation();
            mLocClient.start();
        }

        option=new LocationClientOption();
        myListener=new MyLocationListener();
        mLocClient.registerLocationListener(myListener);
        option.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);
        option.setOpenGps(true);
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        option.setCoorType("bd09ll");
        option.setIsNeedAddress(true);
        option.setNeedDeviceDirect(true);
        option.setScanSpan(1001);
        mLocClient.setLocOption(option);

        mLocClient.start();


    }

    public class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            //mapView 销毁后不在处理新接收的位置
            if (location == null || mMapView == null){
                return;
            }


            MyLocationData locData=new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    .direction(location.getDirection()).latitude(location.getLatitude())
                    .longitude(location.getLongitude())
                    .build();

            mBaiduMap.setMyLocationData(locData);


                if(isFirstLoc){
                    isFirstLoc=false;
                    firstLaLng = new LatLng(location.getLatitude(),
                            location.getLongitude());
                    latLng=firstLaLng;
                    MapStatus.Builder builder=new MapStatus.Builder();
                    builder.target(firstLaLng).zoom(18.0f);
                    mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));

                    MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(firstLaLng);
                    mBaiduMap.animateMapStatus(msu);
                    yuan++;
                    average_speed=location.getSpeed();
                }


                LatLng point=new LatLng(location.getLatitude(),location.getLongitude());

                if(point.longitude>0&&point.latitude>0 && DistanceUtil.getDistance(latLng, point) > 5)
                {
                    ppp.add(point);
                    latLng=point;
                }
                if(ppp.size()>=2){
                    OverlayOptions mOverlay=new PolylineOptions()
                            .width(10)
                            .color(0xAAFF0000)
                            .points(ppp);
                    distance+=DistanceUtil.getDistance(latLng, point);
                    int m= (int)distance;
                    if(m%1000==0&&m!=0){
                       m/=  1000;
                        speak("你已完成"+m+"公里，继续加油");
                    }


                    Overlay mPolyline=(Polyline)mBaiduMap.addOverlay(mOverlay);
                    mPolyline.setZIndex(3);
                    if(isRunning)
                    {
                        average_speed=(average_speed* yuan +location.getSpeed())/(yuan +1);
                        yuan++;
                        Log.i("MyMap",  " 纬度:" + location.getLatitude()
                                + " 经度:" + location.getLongitude() +" "+ ppp.size());
                        String douStr = String.format("%.2f", average_speed);
                        speedText.setText(douStr+"米/秒");
                        douStr = String.format("%.1f", distance);
                        distanceText.setText(douStr+"米");
                        Toast.makeText(MainActivity.this," 纬度:" + location.getLatitude() + " 经度:" + location.getLongitude()
                                +"\n速度："+location.getSpeed()+"大小："+
                                ppp.size()+"\n距离："+distance+"平均速度："+average_speed,Toast.LENGTH_SHORT).show();
                    }

                }




//在日志中打印出点的位置信息，方便观察


        }

    }




//音乐相关函数和类
private void UpdatePlayIcon() {
    if(musicController.isPlaying()){
        imageButton.setImageResource(R.drawable.pause);
        handler.sendEmptyMessage(UPDATE_PROGESS);
    }
    else {
        imageButton.setImageResource(R.drawable.start);
        handler.removeMessages(UPDATE_PROGESS);
    }
}
    private void upDateProgress(){
        seekBar.setProgress(musicController.getCurrentPosition());
        handler.sendEmptyMessageDelayed(UPDATE_PROGESS,500);
    }


    class MyConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            musicController = (MusicService.MyBinder)service;
            UpdatePlayIcon();
            seekBar.setMax(musicController.getDuration());
            seekBar.setProgress(musicController.getCurrentPosition());

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }
    private void startMethod1() {
        new Thread(){
            @Override
            public void run() {
                while (flag){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    handler.sendEmptyMessage(1);
                }
            }
        }.start();

    }
    @Override
    protected void onStart() {
        super.onStart();
        mBaiduMap.setMyLocationEnabled(true);
        if (mLocClient.isStarted())
            mLocClient.start();


    }

    @Override
    protected void onStop() {
        super.onStop();
        handler.removeCallbacksAndMessages(null);
    }

    @Override
    protected void onResume() {
        mMapView.onResume();
        if(musicController!=null){
            handler.sendEmptyMessage(UPDATE_PROGESS);
        }
        super.onResume();
    }

    @Override
    protected void onPause() {
        mMapView.onPause();
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        if (mSpeechSynthesizer != null) {
            mSpeechSynthesizer.stop();
            mSpeechSynthesizer.release();
            mSpeechSynthesizer = null;
        }
        mLocClient.stop();
        mBaiduMap.setMyLocationEnabled(false);
        mMapView.onDestroy();
        mMapView = null;
        unbindService(conn);
        asr.send(SpeechConstant.ASR_CANCEL, "{}", null, 0, 0);
        // 基于SDK集成5.2 退出事件管理器
        // 必须与registerListener成对出现，否则可能造成内存泄露
        asr.unregisterListener(this);
        super.onDestroy();
    }

    //语音识别
    private void initPermissionhe() {
        String permissions[] = {Manifest.permission.RECORD_AUDIO,
                Manifest.permission.ACCESS_NETWORK_STATE,
                Manifest.permission.INTERNET,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
        };

        ArrayList<String> toApplyList = new ArrayList<String>();

        for (String perm : permissions) {
            if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, perm)) {
                toApplyList.add(perm);
                // 进入到这里代表没有权限.
            }
        }
        String tmpList[] = new String[toApplyList.size()];
        if (!toApplyList.isEmpty()) {
            ActivityCompat.requestPermissions(this, toApplyList.toArray(tmpList), 123);
        }

    }


    @Override
    public void onEvent(String name, String params, byte[] data, int offset, int length) {

        String text;
        if (name.equals(SpeechConstant.CALLBACK_EVENT_ASR_PARTIAL)) {
            // 识别相关的结果都在这里
            if (params == null || params.isEmpty()) {
                return;
            }
            if (params.contains("\"final_result\"")) {
                // 一句话的最终识别结果
                Log.i("ars.event", params);

                Gson gson = new Gson();
                ASRresponse asRresponse = gson.fromJson(params, ASRresponse.class);//数据解析转实体bean

                if (asRresponse == null) return;
                //从日志中，得出Best_result的值才是需要的，但是后面跟了一个中文输入法下的逗号，
                if (asRresponse.getBest_result().contains("，")) {//包含逗号  则将逗号替换为空格，这个地方还会问题，还可以进一步做出来，你知道吗？
                    text=asRresponse.getBest_result().replace('，', ' ').trim();//替换为空格之后，通过trim去掉字符串的首尾空格
                } else {//不包含
                    text=asRresponse.getBest_result().trim();
                }
                if(asRresponse.getBest_result().trim().equals("下一首。")){
                    yuan =1;
                    musicController.reset(average_speed);
                    if(average_speed>10)
                        type.setText("当前播放歌曲类别：快歌");
                    else if(average_speed>6)
                        type.setText("当前播放歌曲类别：轻快");
                    else type.setText("当前播放歌曲类别：抒情");
                }else if(asRresponse.getBest_result().trim().contains("停止播放")){
                    musicController.playPause();
                    UpdatePlayIcon();
                }else if(asRresponse.getBest_result().trim().contains("播放音乐")){
                    musicController.playPause();
                    UpdatePlayIcon();
                }else if(asRresponse.getBest_result().trim().contains("开始")){
                    StartSport();
                }else if(asRresponse.getBest_result().trim().contains("结束")){
                    StopSport();
                }else if(asRresponse.getBest_result().trim().contains("暂停")){
                    pauseSport();
                }
            }
        }

    }

    //初始化语音合成
    //  下面是android 6.0以上的动态授权

    /**
     * android 6.0 以上需要动态申请权限
     */
    private void initPermission() {String[] permissions = {
            Manifest.permission.INTERNET,
            Manifest.permission.ACCESS_NETWORK_STATE,
            Manifest.permission.MODIFY_AUDIO_SETTINGS,
            Manifest.permission.WRITE_SETTINGS,
            Manifest.permission.ACCESS_WIFI_STATE,
            Manifest.permission.CHANGE_WIFI_STATE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

        ArrayList<String> toApplyList = new ArrayList<>();

        for (String perm : permissions) {
            if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, perm)) {
                toApplyList.add(perm);
                // 进入到这里代表没有权限.
            }
        }
        String[] tmpList = new String[toApplyList.size()];
        if (!toApplyList.isEmpty()) {
            ActivityCompat.requestPermissions(this, toApplyList.toArray(tmpList), 123);
        }

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        // 此处为android 6.0以上动态授权的回调，用户自行实现。
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    public class SpeechListener implements SpeechSynthesizerListener {
        private static final String TAG = "SpeechListener";

        private MyBluetooth bluetooth;

        public SpeechListener(MyBluetooth bluetooth) {
            this.bluetooth = bluetooth;
        }

        @Override
        public void onSynthesizeStart(String s) {
            Log.i(TAG, "onSynthesizeStart: 开始合成语音...");
            btStop();
        }

        @Override
        public void onSynthesizeDataArrived(String s, byte[] bytes, int i, int i1) {

        }

        @Override
        public void onSynthesizeFinish(String s) {
            Log.i(TAG, "onSynthesizeStart: 合成语音完成...");
        }

        @Override
        public void onSpeechStart(String s) {

        }

        @Override
        public void onSpeechProgressChanged(String s, int i) {

        }

        @Override
        public void onSpeechFinish(String s) {
            Log.i(TAG, "onSpeechFinish: 完成播放");
            btStart();
        }

        @Override
        public void onError(String s, SpeechError speechError) {
            Log.e(TAG, "onError: 语音播放出错了"+speechError.description );
        }

        private void btStart() {
            if (bluetooth != null) {
                bluetooth.start();
            }
        }

        private void btStop() {
            if (bluetooth != null) {
                bluetooth.stop();
            }
        }
    }

    private class DrawThread extends Thread
    {
        private boolean isStopped=false;
        public DrawThread()
        { }

        public void myStop()
        {
            isStopped=true;
        }
        @Override
        public void run() {
            super.run();
            while(!isStopped) {
                bluetooth.initBlueToothHeadset(MainActivity.this, MainActivity.this);
                try {
                    Thread.sleep(4000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            }
        }
}
